<?php

define('DOM_ELEMENT_NODE', 1);
define('DOM_ATTRIBUTE_NODE', 2);
define('DOM_TEXT_NODE', 3);
define('DOM_CDATA_SECTION_NODE', 4);
define('DOM_ENTITY_REFERENCE_NODE', 5);
define('DOM_ENTITY_NODE', 6);
define('DOM_PROCESSING_INSTRUCTION_NODE', 7);
define('DOM_COMMENT_NODE', 8);
define('DOM_DOCUMENT_NODE', 9);
define('DOM_DOCUMENT_TYPE_NODE', 10);
define('DOM_DOCUMENT_FRAGMENT_NODE', 11);
define('DOM_NOTATION_NODE', 12);
define('DOM_PHP_NODE', 13);
define('DOM_PHP_TEXT_NODE', 14);

class HTMLDOM {
	
	var $noWhite = false;
	var $tab = "\t";
	var $document;
	var $parentNode;
	var $nodeType;
	
	var $firstChild;
	var $lastChild;
	var $nextSibling;
	var $previousSibling;
	var $childNodes = array();
	var $attributes = array();
	
	
	function toString() {}
	
	
	// *** PUBLIC METHODS ***
	
	function appendChild($node) {
		$this->childNodes[] = $node;
		$this->updateChildRelations();
	}
	
	function insertBefore($node, $before) {
		/*for ($i = 0; $i < sizeof($this->childNodes); $i++) {
			if ($this->childNodes[$i] === $before) {
				array_splice($this->childNodes, $i, 0, array($node));
				$this->updateChildRelations();
				return;
			}
		}*/
		if ($before) {
			array_splice($this->childNodes, $before->index, 0, array($node));
			$this->updateChildRelations();
		} else {
			$this->appendChild($node);
		}
	}
	
	function removeChild($node) {
		/*for ($i = 0; $i < sizeof($this->childNodes); $i++) {
			if ($this->childNodes[$i] === $node) {
				array_splice($this->childNodes, $i, 1);
				$this->updateChildRelations();
				$node->clearRelations();
				return $node;
			}
		}*/
		if ($node) {
			array_splice($this->childNodes, $node->index, 1);
			$node->clearRelations();
			$this->updateChildRelations();
			return $node;
		}
		return null;
	}
	
	function replaceChild($oldNode, $newNode) {
		/*for ($i = 0; $i < sizeof($this->childNodes); $i++) {
			if ($this->childNodes[$i] === $oldNode) {
				array_splice($this->childNodes, $i, 1, array($newNode));
				$this->updateChildRelations();
				$oldNode->clearRelations();
				return $oldNode;
			}
		}*/
		if ($oldNode && $newNode) {
			array_splice($this->childNodes, $oldNode->index, 1, array(null));
			$this->childNodes[$oldNode->index] = $newNode;
			$oldNode->clearRelations();
			$this->updateChildRelations();
			return $oldNode;
		}
		return null;
	}
	
	function hasChildNodes() {
		return (sizeof($this->childNodes) > 0);
	}
	
	function cloneNode($deep = false) {
		$copy = clone $this;
		$copy->clearRelations();
		if (!$deep) $copy->childNodes = array();
		return $copy;
	}
	
	// *** PROTECTED METHODS ***
	
	function updateChildRelations() {
		$numChildren = sizeof($this->childNodes);
		if ($numChildren == 0) return;
		
		$this->firstChild = $this->childNodes[0];
		$this->lastChild = $this->childNodes[$numChildren - 1];
		
		for ($i = 0; $i < $numChildren; $i++) {
			$node = $this->childNodes[$i];
			$node->parentNode = $this;
			$node->index = $i;
			if (0 < $i) $node->previousSibling = $this->childNodes[$i - 1];
			if ($i < $numChildren - 1) $node->nextSibling = $this->childNodes[$i + 1];
		}
	}
	
	function clearRelations() {
		unset($this->parentNode);
		unset($this->nextSibling);
		unset($this->previousSibling);
		$this->index = null;
	}
}

?>